﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Comm.PublicClass;

namespace Wasion.HHU.Services
{
    public class Manager    
    { 
        public static int OrderWait; //指令超时时间         

        private static List<TCommtype> CommLst;  //串口表    
        /// <summary>
        /// 发指令相关参数，依次为  字节间延时  指令间延时    前导符  后导符  重试次数  通信参数配置的重试次数  临时设置的重试次数
        /// </summary>
        private static int ByteDelay, ByteOvertime, OrderDelay, RedoTimes, NormalRedoTimes, SpecialRedoTimes;

        private static int OrderLoad;       //add by xd 2013-02-28 返回帧缓冲延时

        public static int MaxOrderWait  //获取指令最大等待时间  shaunwang 2014-8-20
        {
            get { return OrderWait * RedoTimes; }
        }


        //设备及指令类
        private class Torderinfo
        {
            private string fmeterid = string.Empty;  //设备ID
            private int orderindex = -1;  //当前指令序号
            private List<CommConst.TOrdertype> order; //指令列表            

            public string MeterID
            {
                get { return fmeterid; }
                set { fmeterid = value; }
            }

            public int OrderIndex
            {
                get { return orderindex; }
                set { orderindex = value; }
            }


            /// <summary>
            /// 在指令列表中找一个空的位置
            /// </summary>
            /// <returns></returns>
            private int FindPlace()
            {
                int newplace = -1;
                if (order.Count <= 10)  //指令少于10个时直接加个新位置
                    return newplace;
                for (int i = 0; i < order.Count; i++)
                {
                    if (order[i].OrderDone)
                    {
                        newplace = i;
                        break;
                    }
                }
                return newplace;
            }

            //添加指令
            public int addOrder(CommConst.TOrdertype aOrder, ref string errinfo)
            {
                try
                {
                    if (order == null) 
                        order = new List<CommConst.TOrdertype>();

                    CommConst.TOrdertype orderitem = aOrder;

                    //add by shaunwang  2014-5-5  如果有临时设置的重试次数  优先用之
                    if (SpecialRedoTimes > 0)
                        RedoTimes = SpecialRedoTimes;
                    else
                        RedoTimes = NormalRedoTimes;

                    orderitem.maxdotimes = RedoTimes;
                    orderitem.maxovertime = OrderWait;

                    int newplace = FindPlace(); //shaunwang 2014-11-4 
                    if (newplace < 0)
                    {
                        order.Add(orderitem);
                        newplace = order.Count - 1;
                    }
                    else
                        order[newplace] = orderitem;
                    return newplace + 1;
                }
                catch (Exception ex)
                {
                    errinfo = "添加指令失败:" + ex.Message;           
                    return -1;
                }
            }
            //获取正在执行的指令

            public CommConst.TOrdertype getDoingOrder()
            {
                if (orderindex < 0 || orderindex >= order.Count) return null;
                if (order[orderindex].SendFlag != CommConst.CommFlag.CommSending)
                {
                    for (int i = 0; i < order.Count; i++)
                    {
                        if (order[i].SendFlag == CommConst.CommFlag.CommSending)
                        {
                            orderindex = i;
                            break;
                        }
                    }
                }
                return order[orderindex];
            }

            //获取下一个要执行的指令
            public CommConst.TOrdertype getNextOrder()
            {
                try
                {
                    if (order.Count == 0)
                        return null;
                    DateTime comparetime = new DateTime();
                    bool havecomparetime = false;
                    CommConst.TOrdertype nextorder = null;
                    int newindex = -1;

                    //for (CommConst.OrderLevel l = CommConst.OrderLevel.OLRed; l >= CommConst.OrderLevel.OLBlue; l--)
                    //{
                    for (int i = 0; i < order.Count; i++)
                    {
                        if (order[i].SendFlag == CommConst.CommFlag.CommSending)
                        {
                            nextorder = order[i];
                            newindex = i;
                            break;
                        }
                        else
                            if (order[i].SendFlag == CommConst.CommFlag.CommNone)// && order[i].orderlevel == l
                            {
                                if (order[i].order != string.Empty)
                                {
                                    try
                                    {
                                        if (!havecomparetime || DateTime.Compare(comparetime, order[i].createtime) > 0)
                                        {
                                            comparetime = order[i].createtime;
                                            nextorder = order[i];
                                            newindex = i;
                                            havecomparetime = true;
                                        }
                                    }
                                    catch
                                    {
                                        orderindex = i;
                                        nextorder = order[i];
                                        return nextorder;
                                    }
                                }
                                else
                                {
                                    order[i].Fail(false, "指令为空");
                                }
                            }
                    }
                    //}

                    orderindex = newindex;

                    return nextorder;
                }
                catch (Exception ex)
                {
                    return null;
                }
            }


            //停止发指令
            public void stopOrder(string sreason)
            {
                try
                {
                    
                    if (order != null)
                    {
                        for (int i = 0; i < order.Count; i++)
                        {
                            if (!order[i].OrderDone)
                                order[i].Fail(false, sreason);
                        }
                    }
                }
                catch (Exception ex)
                {

                }

            }

            public void clearOrder()
            {
                try
                {
                    if (order != null)
                    {
                        order.Clear();
                    }
                }
                catch (Exception ex)
                {
                }
            }
        }

        //串口信息类
        private class TCommtype
        {
            private string commname; //串口号
            private CommProperty.CommMode commmode = CommProperty.CommMode.RS232; //通信方式  
            private int baudrate; //
            private int handbaudrate; //握手波特率
            private int databits; //
            private int handdatabits;  //握手数据位
            //public string stopbits; //
            private bool havewake = true;  //是否有前导符
            private string parity; //
            private bool onopen = false; //是否打开
            private bool onuse = false; //是否占用   
            private bool onprepare = false;  //初始化状态标志
            private bool sending = false;   //是否可以发指令
            private int meterindex = -1;  //当前正在发送指令的设备索引
            private List<Torderinfo> orderlst; //指令列表             
            private int RecHandle = 0;  //接收消息处理句柄
            private ComClient CommObj = null;  //串口通信类
            private Thread SendThread = null;    //发指令线程
            private CommConst.TOrdertype currentOrder = null;  //当前正在执行的指令  
            private CommConst.TOrdertype UploadOrder = null;  //用于处理主动上传的虚拟指令  2019-8-19 shaunwang 
            private Thread WatchThread = null;  //监控指令状态 
            private readonly object balancelock = new object();  //互斥锁
            public string BLEHandle = "";  //低功耗蓝牙句柄

            public string CommName
            {
                get { return commname; }
                set { commname = value; }
            }
            public int BaudRate
            {
                get { return baudrate; }
                set { baudrate = value; }
            }
            public int HandBaudRate
            {
                get { return handbaudrate; }
                set { handbaudrate = value; }
            }

            public int Databit
            {
                get { return databits; }
                set { databits = value; }
            }

            public int HandDatabit
            {
                get { return handdatabits; }
                set { handdatabits = value; }
            }

            public string Parity
            {
                get { return parity; }
                set { parity = value; }
            }

            public CommProperty.CommMode CommMode
            {
                get { return commmode; }
                set { commmode = value; }
            }

            public bool HaveWake
            {
                get { return havewake; }
                set { havewake = value; }
            }

            public bool Sending   //是否可以发指令
            {
                get { return sending; }
            }

            public bool OnUse
            {
                get { return checkUse(); }
                set { onuse = value; }
            }

            private int GetMeterIndex(string aMeterid)
            {
                try
                {
                    int index = -1;
                    if (orderlst == null)  //设备和指令表还未创建
                    {
                        orderlst = new List<Torderinfo>();
                    }
                    else
                    {
                        for (int i = 0; i < orderlst.Count; i++)
                        {
                            if (orderlst[i].MeterID == aMeterid)
                            {
                                index = i;
                                break;
                            }
                        }
                    }


                    return index;
                }
                catch (Exception ex)
                {
                    return -1;
                }
            }

            //获取当前正在执行的指令
            public CommConst.TOrdertype getCurrentOrder()
            {
                if (orderlst == null || meterindex < 0 || meterindex >= orderlst.Count)
                    return null;
                CommConst.TOrdertype findorder = currentOrder;
                if (findorder != null && findorder.SendFlag != CommConst.CommFlag.CommSending)
                {
                    findorder = null;
                    for (int i = 0; i < orderlst.Count; i++)
                    {
                        findorder = orderlst[i].getDoingOrder();
                        if (findorder != null && findorder.SendFlag == CommConst.CommFlag.CommSending)
                        {
                            meterindex = i;
                            break;
                        }
                    }
                }
                return findorder;
            }

            /// <summary>
            /// 监测当前指令，负责在没有指令的时候释放串口，或者当前有指令且收到了返回，但是在允许的时间范围内没有解析完毕
            /// </summary>
            private void watchTimer_Elapsed()
            {
                while (sending)
                {
                    //Application.DoEvents();
                    Thread.Sleep(2);
                    try
                    {
                        if (currentOrder == null)
                        {
                            onuse = false;
                            continue;
                        }
                        if (currentOrder.SendFlag == CommConst.CommFlag.CommSending
                            && currentOrder.Msgflag == CommConst.CommFlag.CommSending
                            && currentOrder.waitreturn)
                        {
                            Thread.Sleep(CommConst.WatchInterval);
                            currentOrder.overtime += CommConst.WatchInterval;

                            if (currentOrder.overtime >= currentOrder.maxovertime)  //超时了
                            {
                                if (!string.IsNullOrEmpty(currentOrder.recstr) && currentOrder.recstr.Length > 8)
                                {
                                    currentOrder.Fail(true, "收到应答，没解析");
                                }

                                onuse = false; //释放串口
                            }
                        }
                        else
                            onuse = false; //释放串口   

                    }
                    catch (Exception ex)
                    {
                    }
                }

            }

            //添加指令
            public int addOrderInfo(CommConst.TOrdertype aOrder, ref string errinfo)
            {
                int rs = 1;
                try
                {
                    if (this.commmode != aOrder.connMode) //新增指令的通信方式不一样时要重置，比如串口接了其他设备(光口、猫)
                    {
                        this.onprepare = false;
                        this.commmode = aOrder.connMode;
                    }                   


                    Torderinfo orderinfoitem;
                    int MeterIndex = GetMeterIndex(aOrder.fmeterid);
                    if (MeterIndex < 0) //没找到设备则新增一个
                    {
                        orderinfoitem = new Torderinfo();
                        orderinfoitem.MeterID = aOrder.fmeterid;
                        orderinfoitem.OrderIndex = -1;
                        orderlst.Add(orderinfoitem);
                        MeterIndex = orderlst.Count - 1;
                    }
                    else
                    {
                        orderinfoitem = orderlst[MeterIndex];
                    }
                    //RecHandle = aOrder.fmsghandle;                    

                    //向该设备下添加指令
                    return orderinfoitem.addOrder(aOrder, ref errinfo);

                }
                catch (Exception ex)
                {
                    return -1;
                }
            }

            //检查当前是否处于空闲状态  可以发下一条指令
            private bool checkUse()
            {
                bool isuse = currentOrder != null && currentOrder.SendFlag == CommConst.CommFlag.CommSending;
                return isuse;
            }


            //发指令函数
            public void sendOrder()
            {
                string debug1 = "";     //调试错误

                try
                {
                    while (sending)
                    {
                        try
                        {
                            int rs = 0;
                            string errinfo = string.Empty;                            
                            try
                            {
                                //Application.DoEvents();
                                Thread.Sleep(2);
                            }
                            catch { }
                            if (!OnUse)
                            {
                                //CommConst.TOrdertype nextOrder = null;
                                try
                                {
                                    if (orderlst == null || meterindex >= orderlst.Count)  //shaunwang 2014-12-1
                                        continue;
                                    currentOrder = orderlst[meterindex].getNextOrder();
                                }
                                catch
                                {

                                }
                                if (currentOrder == null)  //未找到合法指令，即当前设备的指令执行完了
                                {                                  
                                    meterindex += 1;
                                    if (meterindex >= orderlst.Count)  //所有设备都执行完了
                                        meterindex = 0;
                                    continue;  
                                     
                                }
                                CommObj.OutTime = OrderWait;

                                if (commmode == CommProperty.CommMode.WSBLE && BLEHandle != currentOrder.MACAddr)  //蓝牙通信且MAC地址有变时要重连
                                    onprepare = false;

                                if (!onprepare || currentOrder.ResetComm)   //串口没有准备或者指令中指定的要重置
                                {                                    
                                    CommObj.EventReceive = null;
                                    
                                    switch (commmode)
                                    {
                                        case CommProperty.CommMode.OPTICAL: //光口
                                        case CommProperty.CommMode.OPTICAL1107:
                                            rs = TOptical.Prepare(CommObj, handbaudrate, handdatabits, currentOrder, ref errinfo);
                                            onprepare = !onprepare ? rs > 0 : onprepare;
                                            break;
                                        case CommProperty.CommMode.BLELOW:  //低功耗蓝牙
                                            rs = TBLELow.Prepare(CommObj, currentOrder, ref errinfo);
                                            onprepare = !onprepare ? rs > 0 : onprepare;
                                            break;
                                        case CommProperty.CommMode.WSBLE:  //威胜蓝牙
                                            rs = TWSBLE.Prepare(CommObj, currentOrder, ref errinfo);
                                            onprepare = !onprepare ? rs > 0 : onprepare;
                                            break;
                                        default:
                                            onprepare = true;
                                            break;
                                    }
                                    if (!onprepare)
                                        currentOrder.Fail(false, errinfo);
                                    else
                                        BLEHandle = currentOrder.MACAddr;  //记录蓝牙连接句柄
                                }

                                
                                if (currentOrder.SendFlag == CommConst.CommFlag.CommNone)
                                {                                    
                                    try
                                    {                                   
                                        onuse = true;
                                        try
                                        {
                                            Thread.Sleep(OrderDelay); 
                                        }
                                        catch (Exception ex)
                                        {
                                        }

                                        //某些通信方式需要处理下指令
                                        switch (currentOrder.connMode)
                                        {
                                            case CommProperty.CommMode.BLELOW:  //低功耗蓝牙
                                                //if (BLEHandle != "")
                                                //    currentOrder.MACAddr = BLEHandle;  //蓝牙句柄
                                                //rs = TBLELow.TransOrder(currentOrder, ref errinfo);
                                                break;
                                            default:
                                                break;
                                        }
                                        if (rs < 0)
                                        {
                                            currentOrder.Fail(false, errinfo);
                                            continue;
                                        }



                                        //Log.WriteDeBugLog("进入发送" + commname + ":" + nextOrder.SendFlag);
                                        debug1 = "1";
                                        currentOrder.recstr = string.Empty;
                                        currentOrder.errorinfo = string.Empty;

                                        currentOrder.dotimes += 1;
                                        debug1 = "2";                                        

                                        string outorder = currentOrder.order;
                                        CommObj.SRMode = currentOrder.srmode;
                                        
                                        CommObj.EventReceive = currentOrder.GetCorrectFrame; 

                                        currentOrder.Msgflag = CommConst.CommFlag.CommSending;
                                        currentOrder.SendFlag = CommConst.CommFlag.CommSending;                                     

                                        //调用串口操作类发送
                                        if (currentOrder.waitreturn)
                                            rs = CommObj.SendString(ref outorder, ref errinfo);
                                        else
                                            rs = CommObj.SendString(outorder, ref errinfo);

                                        CommObj.EventReceive = null;
                                        currentOrder.orderinfo = string.Empty;
                                        if (rs >= 0)  //发送成功
                                        {
                                            if (currentOrder.waitreturn)
                                            {
                                                if (outorder.Length == 0) //超时无返回
                                                {
                                                    string err = "无应答";
                                                    try
                                                    {
                                                        currentOrder.errrecstr = CommObj.GetErrorReceive();  //获取返回的原始帧
                                                        if (!string.IsNullOrEmpty(currentOrder.errrecstr) && currentOrder.GetCorrectFrame != null)
                                                        {
                                                            errinfo = string.Empty;
                                                            string correctrec = currentOrder.GetCorrectFrame(ref currentOrder.errrecstr, ref errinfo);
                                                            if (!string.IsNullOrEmpty(errinfo))  //获取原始帧错误原因
                                                                err = errinfo;
                                                        }
                                                    }
                                                    finally
                                                    {
                                                        currentOrder.Fail(true, err);
                                                    }
                                                }
                                                else
                                                {
                                                    if (currentOrder.GetCorrectFrame != null)
                                                    {
                                                        outorder = currentOrder.GetCorrectFrame(ref outorder, ref errinfo);
                                                        if (string.IsNullOrEmpty(outorder))
                                                        {
                                                            currentOrder.Fail(true, errinfo);
                                                            continue;
                                                        }
                                                    }

                                                    currentOrder.RecDelay = rs;
                                                    currentOrder.recstr = outorder;

                                                    currentOrder.SendFlag = CommConst.CommFlag.CommReceived;
                                                    currentOrder.Msgflag = CommConst.CommFlag.CommReceived;
                                                    if (currentOrder.DoAnalysis != null)
                                                        currentOrder.DoAnalysis(currentOrder);
                                                }                                                    
                                            }
                                            else
                                            {
                                                currentOrder.Success();
                                            }                                        
                                        }
                                        else   //发送失败
                                        {
                                            currentOrder.SendFail("发送失败:" + errinfo);
                                            closeComm(ref errinfo);
                                        }
                                    }
                                    finally
                                    {
                                        onuse = false; //释放串口
                                    }
                                }

                            }
                        }
                        catch (Exception ex)
                        {
                            //Log.WriteDeBugLog(debug1 + "catch2");
                        }

                    }
                }
                catch (Exception ex)
                {

                }
                finally
                {
                }
            }

            //启动发指令
            public int startOrder(ref string errinfo)
            {
                lock (balancelock)
                {
                    int result = -1;
                    if (CommObj == null)
                    {
                        CommObj = new ComClient();
                    }


                    CommObj.ByteDelay = ByteDelay;
                    CommObj.ByteOvertime = ByteOvertime;
                    CommObj.OrderLoad = OrderLoad;
                    if (!onopen)
                        onopen = CommObj.OpenComm(commname, baudrate, databits, 1, Int16.Parse(parity), ref errinfo) > 0;
                    if (!onopen)
                    {
                        stopOrder(errinfo);

                        return result; //打开串口失败

                    }
                    Thread.Sleep(50);
                    try
                    {                       
                        if (SendThread == null || SendThread.ThreadState == ThreadState.Stopped || !sending) //为空则创建发指令线程
                        {
                            sending = true;
                            
                            SendThread = new Thread(new ThreadStart(sendOrder));
                            SendThread.IsBackground = true;
                            SendThread.Name = commname + "发指令线程";
                            meterindex = 0; //从第一个设备开始
                            SendThread.Start();
                        }

                        result = 1;
                    }
                    catch (Exception ex)
                    {
                        errinfo = "启动发指令失败:" + ex.Message;   
                    }
                    return result;
                }                
            }


            //启动监听
            //public int startListen(CommConst.TOrdertype aOrder, ref string errinfo)   
            //{
            //    int result = -1;
            //    if (CommObj == null)
            //    {
            //        CommObj = new ComClient();
            //    }
            //    UploadOrder = aOrder;     
            //    UploadOrder.Direction = 1;

            //    CommObj.ByteDelay = ByteDelay;
            //    CommObj.ByteOvertime = ByteOvertime;
            //    CommObj.OrderLoad = OrderLoad;
            //    CommObj.SRMode = aOrder.srmode;
            //    CommObj.EventReceive = aOrder.GetCorrectFrame;  //获取正确返回委托
            //    CommObj.DoAfterReceive = aOrder.DoAfterReceive;  //收到数据之后执行的操作
            //    if (!onopen)
            //        onopen = CommObj.OpenComm(commname, baudrate, databits, 1, Int16.Parse(parity), ref errinfo) > 0;
            //    if (!onopen)
            //    {
            //        return result; //打开串口失败

            //    }

            //    if (!onprepare || aOrder.ResetComm)   //串口没有准备或者指令中指定的要重置
            //    {
            //        CommObj.EventReceive = null;

            //        switch (commmode)
            //        {
            //            case CommProperty.CommMode.OPTICAL: //光口
            //            case CommProperty.CommMode.OPTICAL1107:
            //                int rs = TOptical.Prepare(CommObj, handbaudrate, handdatabits, aOrder, ref errinfo);
            //                onprepare = !onprepare ? rs > 0 : onprepare;
            //                break;

            //            case CommProperty.CommMode.WSBLE:  //威胜蓝牙
            //                rs = TWSBLE.Prepare(CommObj, aOrder, ref errinfo);
            //                onprepare = !onprepare ? rs > 0 : onprepare;
            //                break;
            //            default:
            //                onprepare = true;
            //                break;
            //        }
            //        CommObj.EventReceive = aOrder.GetCorrectFrame; 
            //        if (!onprepare)
            //            return result; //准备工作失败
            //    }


            //    return 1;
            //}

            /// <summary>
            /// 对主动上报的发确认 2019-8-19
            /// </summary>
            /// <param name="aOrder"></param>
            /// <param name="errinfo"></param>
            /// <returns></returns>
            //public int uploadConfirm(CommConst.TOrdertype aOrder, ref string errinfo)
            //{
            //    int rs = 1;
            //    try
            //    {
            //        if (aOrder != null && !string.IsNullOrEmpty(aOrder.order))
            //        {
            //            aOrder.Msgflag = CommConst.CommFlag.CommSending;
            //            aOrder.SendFlag = CommConst.CommFlag.CommSending;

            //            //调用串口操作类发送
            //            rs = CommObj.SendString(aOrder.order, ref errinfo);

            //            aOrder.Success();
            //        }
            //    }
            //    catch (Exception ex)
            //    {
            //        rs = -1;
            //        errinfo = ex.Message;
            //    }
            //    return rs;
            //}


            //停止发指令
            //public int stopOrder(string sreason)
            //{
            //    int result = -1;
            //    sending = false;
            //    try
            //    {                    
            //        if (orderlst != null)
            //        {
            //            for (int i = 0; i < orderlst.Count; i++) //shaunwang 2014-11-6
            //                orderlst[i].stopOrder(sreason);
            //        }
            //        if (CommObj != null)
            //            CommObj.StopWaitting();
            //        //if (SendThread != null)   
            //        //    SendThread.Abort();  shaunwang win7系统会卡在这里    


            //        GC.Collect();
            //        result = 1;
            //    }
            //    catch (Exception ex)
            //    {
            //        return -1;
            //    }
            //    finally
            //    {
            //        onuse = false;
            //    }
            //    return result;

            //}

            //清空指令
            //public int clearOrder()
            //{
            //    int result = -1;
            //    try
            //    {
            //        if (orderlst != null)
            //            orderlst.Clear();

            //        if (CommObj != null)
            //            CommObj.StopWaitting();
            //        meterindex = 0;
            //        onuse = false;

            //    }
            //    catch (Exception ex)
            //    {
            //    }
            //    return result;
            //}



            //刷新波特率
            //public int refreshBaudRate(int newbaudrate, ref string errinfo)
            //{
            //    try
            //    {
            //        if (CommObj != null)
            //        {
            //            baudrate = newbaudrate;
            //            CommObj.BaudRate = newbaudrate;

            //            //if (onopen)
            //            //{
            //            //    onopen = CommObj.OpenComm(commname, baudrate, databits, 1, Int16.Parse(parity), ref errinfo) > 0;
            //            //    if (!onopen)
            //            //        return -1; //打开串口失败                            
            //            //}
            //        }
            //        Thread.Sleep(100);
            //        return 1;
            //    }
            //    catch (Exception ex)
            //    {
            //        return -1;
            //    }
            //}


            //关闭串口
            //public int closeComm(ref string errinfo)
            //{
            //    int rs = -1;
            //    try
            //    {
            //        if (CommObj != null)
            //        {
            //            if (onprepare)
            //            {
            //                switch (commmode)
            //                {
            //                    case CommProperty.CommMode.BLELOW: //低功耗蓝牙
            //                    //case CommProperty.CommMode.WSBLE: //威胜蓝牙
            //                        for (int i = 0; i < orderlst.Count; i++)
            //                        {
            //                            Torderinfo orderinfoitem = orderlst[i];

            //                            if (commmode == CommProperty.CommMode.BLELOW)
            //                                rs = TBLELow.Disconect(CommObj, BLEHandle, Int16.Parse(orderinfoitem.MeterID), ref errinfo); 
            //                            //else
            //                            //    rs = TWSBLE.Disconect(CommObj, orderinfoitem.BLEHandle, Int16.Parse(orderinfoitem.MeterID), ref errinfo);
            //                        }
            //                        onprepare = false;
            //                        break;
            //                }
            //            }                        
                        
            //            rs = CommObj.CloseComm(ref errinfo);
            //        }

            //    }
            //    catch (Exception ex)
            //    {
            //        errinfo = ex.Message;
            //    }
            //    CommObj.EventReceive = null;
            //    CommObj.DoAfterReceive = null;
            //    onopen = false;
            //    onuse = false; //释放串口
            //    return rs;
            //}


            //关闭和某个表的连接
        //    public int closeComm(string meterid, ref string errinfo)
        //    {
        //        int rs = -1;
        //        try
        //        {
        //            if (CommObj != null)
        //            {
        //                if (onprepare)
        //                {
        //                    switch (commmode)
        //                    {
        //                        case CommProperty.CommMode.BLELOW: //低功耗蓝牙
        //                        //case CommProperty.CommMode.WSBLE: //威胜蓝牙
        //                            Torderinfo orderinfoitem;
        //                            int MeterIndex = GetMeterIndex(meterid);
        //                            if (MeterIndex < 0) //没找到设备
        //                            {
        //                                errinfo = "cant't find meter[" + meterid +"]";
        //                                return rs;
        //                            }
        //                            else
        //                            {
        //                                orderinfoitem = orderlst[MeterIndex];
        //                                if (commmode == CommProperty.CommMode.BLELOW)
        //                                    rs = TBLELow.Disconect(CommObj, BLEHandle, Int16.Parse(orderinfoitem.MeterID), ref errinfo);
        //                                //else
        //                                //    rs = TWSBLE.Disconect(CommObj, orderinfoitem.BLEHandle, Int16.Parse(orderinfoitem.MeterID), ref errinfo);
        //                            }

        //                            onprepare = false;
        //                            break;
        //                    }
        //                }
        //            }

        //        }
        //        catch (Exception ex)
        //        {
        //            errinfo = ex.Message;
        //        }
        //        CommObj.EventReceive = null;
        //        CommObj.DoAfterReceive = null;
        //        onopen = false;
        //        onuse = false; //释放串口
        //        return rs;
        //    }

        //}


        //根据串口号获取在串口表中的类
        private static TCommtype GetCommType(string aComm)
        {
            TCommtype commtype = null;
            try
            {
                for (int i = 0; i < CommLst.Count; i++)
                {
                    if (CommLst[i].CommName.ToUpper() == aComm.ToUpper())
                    {
                        commtype = CommLst[i];
                        break;
                    }
                }
            }
            catch (Exception ex)
            {

            }
            return commtype;
        }

        /// <summary>
        /// 初始化
        /// </summary>
        //public int InitCommInfo(ref string errinfo)
        //{
        //    int rs = 0;
        //    try
        //    {
        //        StringBuilder temp = new StringBuilder(1024);
        //        string[] Commlist, BaudRatelist, HandBaudRatelst, Databitlist, HandDatabitlst, Paritylist, Modelist;
        //        char splitchar = ',';
        //        int i = 0;
        //        int index;
        //        TCommtype CommItem;

        //        //CommConst.StartUpPath = Application.StartupPath;

        //        if (CommLst == null)
        //            CommLst = new List<TCommtype>();

        //        string inifilename = CommConst.StartUpPath + "\\" + CommConst.FIniFileName;
        //        //串口号
        //        Commlist = RWOutFiles.GetINIString(inifilename, "COM", "CommName", "COM1").Split(splitchar);

        //        //波特率
        //        BaudRatelist = RWOutFiles.GetINIString(inifilename, "COM", "BaudRate", "2400").Split(splitchar);

        //        //握手波特率
        //        HandBaudRatelst = RWOutFiles.GetINIString(inifilename, "COM", "HandBaudRate", "300").Split(splitchar);
                

        //        //数据位
        //        Databitlist = RWOutFiles.GetINIString(inifilename, "COM", "Databit", "8").Split(splitchar);

        //        //握手数据位
        //        HandDatabitlst = RWOutFiles.GetINIString(inifilename, "COM", "HandDatabit", "8").Split(splitchar);

        //        //校验方式
        //        Paritylist = RWOutFiles.GetINIString(inifilename, "COM", "Parity", "2").Split(splitchar);

        //        //通信方式
        //        Modelist = RWOutFiles.GetINIString(inifilename, "COM", "ConnMode", "1").Split(splitchar);

        //        //多功能板类别
        //        //Functionlist = RWOutFiles.GetINIString(inifilename, "COM", "WSFunction", "").Split(splitchar);

        //        //台体串口  shaunwang 2015-9-19
        //        string SourceComm = RWOutFiles.GetINIString(inifilename, "SYS", "PlatCommuAddr", "");


        //        //工况串口 shaunwang 2015-9-19
        //        string DeviceComm = RWOutFiles.GetINIString(inifilename, "COM", "DeviceComm", "");


        //        //字节间延时
        //        ByteDelay = Convert.ToInt16(RWOutFiles.GetINIString(inifilename, "Delay", "ByteDelay", "0"));


        //        //字节间超时
        //        ByteOvertime = Convert.ToInt16(RWOutFiles.GetINIString(inifilename, "Delay", "ByteOvertime", "120"));

        //        //指令间延时
        //        OrderDelay = Convert.ToInt16(RWOutFiles.GetINIString(inifilename, "Delay", "OrderDelay", "0"));

        //        //指令超时
        //        OrderWait = Convert.ToInt16(RWOutFiles.GetINIString(inifilename, "Delay", "OrderWait", "0")) * 1000;

        //        //重读次数
        //        NormalRedoTimes = Convert.ToInt16(RWOutFiles.GetINIString(inifilename, "Delay", "RedoTimes", "0"));
        //        SpecialRedoTimes = -1;  //add by shaunwang  2014-5-5  临时设置的重试次数默认为-1

        //        //前导符
        //        CommConst.WakeChar = RWOutFiles.GetINIString(inifilename, "Delay", "WakeChar", "");
        //        CommConst.WakeChar = CommConst.WakeChar.Replace(" ", "");
        //        if (CommConst.WakeChar.Length % 2 != 0)
        //            CommConst.WakeChar = "0" + CommConst.WakeChar;

        //        //后导符
        //        CommConst.DelayChar = RWOutFiles.GetINIString(inifilename, "Delay", "DelayChar", "");
        //        CommConst.DelayChar = CommConst.DelayChar.Replace(" ", "");
        //        if (CommConst.DelayChar.Length % 2 != 0)
        //            CommConst.DelayChar = "0" + CommConst.DelayChar;


        //        //返回帧缓冲延时 add by xd 2013-02-28
        //        OrderLoad = Convert.ToInt16(RWOutFiles.GetINIString(inifilename, "Delay", "OrderLoad", "130"));


        //        for (i = 0; i < Commlist.Length; i++)
        //        {
        //            //判断串口表中是否已有该串口
        //            index = -1;
        //            for (int j = 0; j < CommLst.Count; j++)
        //            {
        //                if (CommLst[j] == null)
        //                {
        //                    index = j;
        //                    break;
        //                }
        //                else
        //                {
        //                    if (CommLst[j].CommName == Commlist[i])
        //                    {
        //                        string err = string.Empty;
        //                        index = j;
        //                        //CommLst[j].BaudRate = Functionlist[i] == "1" ? 9600 : Convert.ToInt32(BaudRatelist[i]);
        //                        CommLst[j].BaudRate = Convert.ToInt32(BaudRatelist[i]);
        //                        CommLst[j].HandBaudRate = Convert.ToInt32(HandBaudRatelst[i]);
        //                        CommLst[j].Databit = Convert.ToInt32(Databitlist[i]);
        //                        CommLst[j].HandDatabit = Convert.ToInt32(HandDatabitlst[i]);
        //                        CommLst[j].Parity = Paritylist[i];
        //                        CommLst[j].refreshBaudRate(CommLst[j].BaudRate, ref err);                               
        //                        break;
        //                    }
        //                }
        //            }
        //            if (index < 0)
        //            {
        //                CommItem = new TCommtype();
        //                CommItem.CommName = Commlist[i];
        //                //CommItem.BaudRate = Functionlist[i] == "1" ? 9600 : Convert.ToInt32(BaudRatelist[i]);
        //                CommItem.BaudRate = Convert.ToInt32(BaudRatelist[i]);
        //                CommItem.HandBaudRate = Convert.ToInt32(HandBaudRatelst[i]);
        //                CommItem.Databit = Convert.ToInt32(Databitlist[i]);
        //                CommItem.HandDatabit = Convert.ToInt32(HandDatabitlst[i]);
        //                CommItem.Parity = Paritylist[i];
        //                CommLst.Add(CommItem);
        //                index = CommLst.Count - 1;
        //            }
        //        }


        //        rs = 1;
        //    }
        //    catch (Exception ex)
        //    {
        //        errinfo = ex.Message;
        //        rs = -1;
        //    }
        //    return rs;
        //}


        /// <summary>
        /// 添加指令
        /// </summary>
        /// <param name="aOrder"></param>
        /// <param name="maxovertime"></param>
        /// <returns></returns>
        public int AddOrder(CommConst.TOrdertype aOrder, ref int maxovertime, ref string errinfo)
        {
            int rs = 0;
            try
            {
                TCommtype commtype = GetCommType(aOrder.commname);
                if (commtype == null)
                {
                    errinfo = "未找到串口" + aOrder.commname;
                    return -1;
                }
                rs = commtype.addOrderInfo(aOrder, ref errinfo);
                maxovertime = MaxOrderWait;
            }
            catch (Exception ex)
            {
                errinfo = ex.Message;
                rs = -1;
            }
            return rs;
        }

        /// <summary>
        /// 启动发指令
        /// </summary>
        /// <param name="aOrder"></param>
        /// <returns></returns>
        public int StartOrder(CommConst.TOrdertype aOrder, ref string errinfo)
        {
            int rs = 0;
            try
            {
                TCommtype commtype = GetCommType(aOrder.commname);
                if (commtype == null)
                {
                    errinfo = "未找到串口" + aOrder.commname;
                    return -1;
                }
                rs = commtype.startOrder(ref errinfo);

            }
            catch (Exception ex)
            {
                errinfo = ex.Message;
                rs = -1;
            }
            return rs;
        }

        /// <summary>
        /// 启动监听
        /// </summary>
        /// <param name="aOrder">指令类</param>
        /// <param name="errinfo">回传错误信息</param>
        /// <returns>大于0表示成功  小于0表示失败</returns>
        public int StartListen(CommConst.TOrdertype aOrder, ref string errinfo)
        {
            int rs = 0;
            try
            {
                TCommtype commtype = GetCommType(aOrder.commname);
                if (commtype == null)
                {
                    errinfo = "未找到串口" + aOrder.commname;
                    return -1;
                }
                rs = commtype.startListen(aOrder, ref errinfo);

            }
            catch (Exception ex)
            {
                errinfo = ex.Message;
                rs = -1;
            }
            return rs;
        }


        /// <summary>
        /// 对主动上报的发确认 2019-8-19
        /// </summary>
        /// <param name="aOrder"></param>
        /// <param name="errinfo"></param>
        /// <returns></returns>
        public int UploadConfirm(CommConst.TOrdertype aOrder, ref string errinfo) 
        {
            int rs = 0;
            try
            {
                TCommtype commtype = GetCommType(aOrder.commname);
                if (commtype == null)
                {
                    errinfo = "未找到串口" + aOrder.commname;
                    return -1;
                }
                rs = commtype.uploadConfirm(aOrder, ref errinfo);

            }
            catch (Exception ex)
            {
                errinfo = ex.Message;
                rs = -1;
            }
            return rs;
        }


        /// <summary>
        /// 停止发指令
        /// </summary>
        /// <param name="connMode">通信方式</param>
        /// <param name="meteridOrcommname">表ID或串口号</param>
        /// <returns></returns>
        //public int StopOrder(string meteridOrcommname, ref string errinfo)
        //{
        //    int rs = 0;
        //    try
        //    {
        //        if (string.IsNullOrEmpty(meteridOrcommname))  //停止所有
        //        {
        //            for (int i = 0; i < CommLst.Count; i++)
        //            {
        //                rs = CommLst[i].stopOrder("终止指令");
        //                if (rs < 0)
        //                {
        //                    errinfo = CommLst[i].CommName + "停止指令失败";
        //                    return rs;
        //                }
        //            }
        //        }
        //        else
        //        {
        //            TCommtype commtype = GetCommType(meteridOrcommname);
        //            if (commtype == null)
        //            {
        //                errinfo = "未找到串口" + meteridOrcommname;
        //                return -1;
        //            }
        //            rs = commtype.stopOrder("终止指令");
        //        }

        //    }
        //    catch (Exception ex)
        //    {
        //        errinfo = ex.Message;
        //        rs = -1;
        //    }
        //    return rs;
        //}

        


        /// <summary>
        /// 清空指令
        /// </summary>
        /// <param name="connMode">通信方式</param>
        /// <param name="meteridOrcommname">表ID或串口号</param>
        /// <returns></returns>
        //public int ClearOrder(string meteridOrcommname, ref string errinfo)
        //{
        //    int rs = 0;
        //    try
        //    {
        //        if (string.IsNullOrEmpty(meteridOrcommname))  //清空所有
        //        {
        //            for (int i = 0; i < CommLst.Count; i++)
        //            {
        //                rs = CommLst[i].clearOrder();
        //                if (rs < 0)
        //                {
        //                    errinfo = CommLst[i].CommName + "清空指令失败";
        //                    return rs;
        //                }
        //            }
        //        }
        //        else
        //        {
        //            TCommtype commtype = GetCommType(meteridOrcommname);
        //            if (commtype == null)
        //            {
        //                errinfo = "未找到串口" + meteridOrcommname;
        //                return -1;
        //            }
        //            rs = commtype.clearOrder();
        //        }

        //    }
        //    catch (Exception ex)
        //    {
        //        errinfo = ex.Message;
        //        rs = -1;
        //    }
        //    return rs;
        //}



        /// <summary>
        /// 串口通信用于关闭串口，TCP串口用于断开TCP连接
        /// </summary>
        /// <param name="connMode">通信方式</param>
        /// <param name="meteridOrcommname">表ID或串口号</param>
        /// <returns></returns>
        //public int CloseComm(string meteridOrcommname, ref string errinfo)
        //{
        //    int rs = 0;
        //    try
        //    {
        //        if (string.IsNullOrEmpty(meteridOrcommname))  //关闭所有
        //        {
        //            for (int i = 0; i < CommLst.Count; i++)
        //            {
        //                rs = CommLst[i].stopOrder("终止指令");
        //                if (rs < 0)
        //                {
        //                    errinfo = CommLst[i].CommName + "关闭串口失败";
        //                    return rs;
        //                }
        //                rs = CommLst[i].closeComm(ref errinfo);
        //            }
        //        }
        //        else
        //        {
        //            TCommtype commtype = GetCommType(meteridOrcommname);
        //            if (commtype == null)
        //            {
        //                errinfo = "未找到串口" + meteridOrcommname;
        //                return -1;
        //            }
        //            rs = commtype.stopOrder("终止指令");
        //            if (rs < 0)
        //            {
        //                errinfo = meteridOrcommname + "关闭串口失败";
        //                return rs;
        //            }
        //            rs = commtype.closeComm(ref errinfo);
        //        }

        //    }
        //    catch (Exception ex)
        //    {
        //        errinfo = ex.Message;
        //        rs = -1;
        //    }
        //    return rs;
        //}


        /// <summary>
        /// 串口通信用于关闭和某个表的通信
        /// </summary>
        /// <param name="commname">串口号</param>
        /// <param name="meterid">表ID</param>
        /// <param name="errinfo">回传错误信息</param>
        /// <returns>大于0表示成功  小于0表示失败</returns>
        //public int CloseComm(string commname, string meterid, ref string errinfo)
        //{
        //    int rs = 0;
        //    try
        //    {
        //        TCommtype commtype = GetCommType(commname);
        //        if (commtype == null)
        //        {
        //            errinfo = "未找到串口" + commname;
        //            return -1;
        //        }
        //        rs = commtype.stopOrder("终止指令");
        //        if (rs < 0)
        //        {
        //            errinfo = commname + "关闭串口失败";
        //            return rs;
        //        }
        //        rs = commtype.closeComm(meterid, ref errinfo);

        //    }
        //    catch (Exception ex)
        //    {
        //        errinfo = ex.Message;
        //        rs = -1;
        //    }
        //    return rs;
        //}


        /// <summary>
        /// 刷新波特率
        /// </summary>
        /// <param name="aComm">串口号</param>
        /// <param name="newBaudRate">新波特率</param>
        /// <param name="errinfo"></param>
        /// <returns></returns>
        //public int RefreshBaudRate(string aComm, int newBaudRate, ref string errinfo)
        //{
        //    int rs = 0;
        //    try
        //    {
        //        if (string.IsNullOrEmpty(aComm))  //刷新所有
        //        {
        //            for (int i = 0; i < CommLst.Count; i++)
        //            {
        //                rs = CommLst[i].stopOrder("终止指令");
        //                if (rs < 0)
        //                {
        //                    errinfo = CommLst[i].CommName + "修改波特率失败";
        //                    return rs;
        //                }
        //            }
        //        }
        //        else
        //        {
        //            TCommtype commtype = GetCommType(aComm);
        //            if (commtype == null)
        //            {
        //                errinfo = "未找到串口" + aComm;
        //                return -1;
        //            }
        //            rs = commtype.refreshBaudRate(newBaudRate, ref errinfo);
        //        }

        //    }
        //    catch (Exception ex)
        //    {
        //        errinfo = ex.Message;
        //        rs = -1;
        //    }
        //    return rs;

        }
    }
}
